import re
import os
import zipfile
import rarfile
import shutil
import time

now = 0


def unzip(callback, count):
    def _rename(toFolder):
        for path in os.listdir(toFolder):
            oldPath = os.path.join(toFolder, path)
            newPath = os.path.join(toFolder, path.encode('cp437').decode('gbk'))
            os.rename(oldPath, newPath)
            if os.path.isdir(newPath):
                _rename(newPath)

    def _unzip(zippedFile):
        _path = re.search(r'(.*?)\.zip$', zippedFile).group(1)
        with zipfile.ZipFile(zippedFile, 'r') as zfile:
            zfile.extractall(_path)
        zfile.close()
        try:
            _rename(_path)
        except:
            pass
        for root, dirs, files in os.walk(_path):
            for filename in files:
                fileSpec = os.path.join(root, filename)
                if re.search(r'\.zip$', filename):
                    # os.mkdir(fileSpec + '_')
                    _unzip(fileSpec)
                elif re.search(r'\.rar$', filename):
                    _unrar(fileSpec)
        os.remove(zippedFile)

    def _unrar(zippedFile):
        _path = re.search(r'(.*?)\.rar$', zippedFile).group(1)
        with rarfile.RarFile(zippedFile, 'r') as rfile:
            rfile.extractall(_path)
        rfile.close()
        # _rename(_path)
        for root, dirs, files in os.walk(_path):
            for filename in files:
                fileSpec = os.path.join(root, filename)
                if re.search(r'\.rar$', filename):
                    # os.mkdir(fileSpec + '_')
                    _unrar(fileSpec)
                elif re.search(r'\.zip$', filename):
                    _unzip(fileSpec)
        os.remove(zippedFile)

    def _do(_path, _callback, isFirst):
        global now
        failed = []
        files = os.listdir(_path)
        for file in files:
            res = re.search('(.*?).(zip|rar)$', file)
            if res is not None:
                fileType = res.group(2)
                path = os.path.join(_path, file)
                if fileType == 'zip':
                    # now = now + 1
                    # _callback(now / count)
                    # _unzip(path)
                    try:
                        if isFirst is True:
                            now = now + 1
                        _callback(now / count)
                        _unzip(path)
                    except:
                        if isFirst is True:
                            failed.append(file)
                elif fileType == 'rar':
                    # now = now + 1
                    # _callback(now / count)
                    # _unrar(path)
                    try:
                        if isFirst is True:
                            now = now + 1
                        _callback(now / count)
                        _unrar(path)
                    except:
                        if isFirst is True:
                            failed.append(file)

        return failed

    t1 = time.clock()
    failed = _do('saved files', callback, True)
    failed2 = []
    if len(failed) > 0:
        failed2 = _do('saved files', callback, False)
    t2 = time.clock()
    length = len(failed2)
    print(f'\nsuccess: {now - length}')
    print(f'failed: {length}')
    if length > 0:
        print('they are:')
        for file in failed2:
            print(f'---{file}')
    print(f'unzip cost time: {t2 - t1}s')
